#include "TotalTorque.h"

#include "SpinTorque.h"
#include "AloneTorque.h"
#include "OtherTorque.h"

#include <iostream>

TotalTorque::TotalTorque(Clock clock,Pulse *field,Pulse *current,MultiLayer multiLayer,int layerNumber,NewParameters params)
{
  downBeta1=0;downBeta2=0;upBeta1=0;upBeta2=0;
  Torque torque1,torque2,torque3;
  torque3.setVector(0,0,0);
  torque1=AloneTorque(clock,field,multiLayer[layerNumber]);
  if(multiLayer.getNbLayer()<3)
    {
      if(layerNumber==0)
	{
	  torque2=SpinTorque(clock,current,multiLayer[layerNumber],multiLayer[layerNumber+1],params);
	  torque3=OtherTorque(multiLayer[layerNumber],multiLayer[layerNumber+1]);
	}
      else 
	{
	  torque2=SpinTorque(clock,current,multiLayer[layerNumber],multiLayer[0],params);
	  torque3=OtherTorque(multiLayer[layerNumber],multiLayer[0]);
	}      
      torque1.add(torque2);
      torque1.add(torque3);
    }
  
  else if(multiLayer.getNbLayer()==3)
    {
      if(layerNumber>0) //Spin torque from below + exchange coupling
	{
	  torque2=SpinTorque(clock,current,multiLayer[layerNumber],multiLayer[layerNumber-1],params); 
	  torque3=OtherTorque(multiLayer[layerNumber],multiLayer[layerNumber-1]);	  
	  torque1.add(torque2);
	  torque1.add(torque3);
	  downBeta1=torque2.getBeta1();
	  downBeta2=torque2.getBeta2();
	}
      if((layerNumber+1)<multiLayer.getNbLayer()) //Spin torque from above + exchange coupling
	{
	  torque2=SpinTorque(clock,current,multiLayer[layerNumber],multiLayer[layerNumber+1],params);
	  torque1.add(torque2);
	  torque3=OtherTorque(multiLayer[layerNumber],multiLayer[layerNumber+1]);
	  torque1.add(torque3);
	  upBeta1=torque2.getBeta1();
	  upBeta2=torque2.getBeta2();
	}    
    }
  //Effective field is alone torque + other torque ie torque1 + torque 3
  heff=torque1.getHeff();
  heff.add(torque3.getHeff());

  newAlpha=torque1.getAlpha();
  newGamma=torque1.getGamma();
  newBeta1=torque2.getBeta1(); //only good for one free layer
  newBeta2=torque2.getBeta2(); //only good for one free layer

  x=torque1.getX();
  y=torque1.getY();
  z=torque1.getZ();
}

TotalTorque::~TotalTorque()
{

}

double TotalTorque::getUpBeta1()
{
  return upBeta1;
}

double TotalTorque::getDownBeta1()
{
  return downBeta1;
}

double TotalTorque::getUpBeta2()
{
  return upBeta2;
}

double TotalTorque::getDownBeta2()
{
  return downBeta2;
}
